#include "stdafx.h"
#include "Texture.h"


static KeyValuePair<ETextureFormat, D3DFORMAT> TextureFormatsMapping[] =
{
	{eTexFormat_A8R8G8B8,	D3DFMT_A8R8G8B8},
	{eTexFormat_L8,	D3DFMT_L8},
};


CTexture::CTexture(uint width, uint height, uint levels, ETextureFormat format, bool dynamic)
: m_pTexture(nullptr)
, m_bDynamic(dynamic)
{
	//	texture format
	D3DFORMAT dx_format = value_by_key(format, TextureFormatsMapping);

	//	flags
	uint usage = dynamic ? D3DUSAGE_DYNAMIC : 0;
	D3DPOOL pool = dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;

	//	create texture
	HRESULT hr = g_pDevice->CreateTexture(width, height, levels, usage, dx_format, pool, &m_pTexture, nullptr);
	assert(hr == D3D_OK);
}

CTexture::CTexture(const char* filepath, uint width, uint height, uint levels, ETextureFormat format, bool dynamic)
{
	//	texture format
	D3DFORMAT dx_format = value_by_key(format, TextureFormatsMapping);

	//	flags
	uint usage = dynamic ? D3DUSAGE_DYNAMIC : 0;
	D3DPOOL pool = dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;

	HRESULT hr = D3DXCreateTextureFromFileEx(g_pDevice, filepath, width, height, levels,
		usage, dx_format, pool, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0, nullptr, nullptr, &m_pTexture);
	assert(hr == D3D_OK);
}

CTexture::~CTexture()
{
	SAFE_RELEASE(m_pTexture);
}

ITexture::LockedRect CTexture::Lock(uint level, ETextureLockType lock_type)
{
	assert(m_pTexture);

	uint flags = 0;
	switch(lock_type)
	{
	case eTexLock_Discard:
		flags = m_bDynamic ? D3DLOCK_DISCARD : 0;
		break;

	case eTexLock_ReadOnly:
		assert(!m_bDynamic);	//	reading denied for dynamic textures
		flags = D3DLOCK_READONLY;
		break;
	}

	D3DLOCKED_RECT locked_rect;
	HRESULT hr = m_pTexture->LockRect(level, &locked_rect, nullptr, flags);
	assert(hr == D3D_OK);

	LockedRect data;
	data.pitch = locked_rect.Pitch;
	data.bits = locked_rect.pBits;

	return data;
}

void CTexture::Unlock(uint level)
{
	assert(m_pTexture);

	HRESULT hr = m_pTexture->UnlockRect(level);
	assert(hr == D3D_OK);
}

void CTexture::SavePNG(const char* filepath)
{
	D3DXSaveTextureToFile(filepath, D3DXIFF_PNG, m_pTexture, nullptr);
}

CTexture::operator IDirect3DTexture9* ()
{
	return m_pTexture;
}